
#include <input_manager.h>
#include <config.h>
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/time.h>

static T_InputOpr g_tStdinInputOpr;

static int StdinDeviceInit(void)
{
	struct termios tTTYState;
 
    //get the terminal state
    tcgetattr(STDIN_FILENO, &tTTYState);
	
    //turn off canonical mode
    tTTYState.c_lflag &= ~ICANON;
	
    //minimum of number input read.
    tTTYState.c_cc[VMIN] = 1;
		
    //set the terminal attributes.
    tcsetattr(STDIN_FILENO, TCSANOW, &tTTYState);

	g_tStdinInputOpr.iFd = STDIN_FILENO;

	return 0;
}

static int StdinDeviceExit(void)
{
	struct termios tTTYState;
	 
	//get the terminal state
	tcgetattr(STDIN_FILENO, &tTTYState);

	//turn on canonical mode
	tTTYState.c_lflag |= ICANON;
		
	//set the terminal attributes.
	tcsetattr(STDIN_FILENO, TCSANOW, &tTTYState);

	return 0;
}

static int StdinGetInputEvent(PT_InputEvent ptInputEvent)
{
	struct timeval tTv;
	fd_set tFds;
	char c;
	
	tTv.tv_sec = 0;
	tTv.tv_usec = 0;
	FD_ZERO(&tFds);
	
	FD_SET(STDIN_FILENO, &tFds); //STDIN_FILENO is 0
	select(STDIN_FILENO+1, &tFds, NULL, NULL, &tTv);

	
	if(FD_ISSET(STDIN_FILENO, &tFds))
	{
		ptInputEvent->iType = INPUT_TYPE_STDIN;
		gettimeofday(&ptInputEvent->tTime, NULL);

		c = fgetc(stdin);
		if(c == 'u')
		{
			ptInputEvent->iVal = INPUT_VALUE_UP;
		}
		else if(c == 'n')
		{
			ptInputEvent->iVal = INPUT_VALUE_DOWN;
		}
		else if(c == 'q')
		{
			ptInputEvent->iVal = INPUT_VALUE_EXIT;
		}
		else
		{
			ptInputEvent->iVal = INPUT_VALUE_UNKNOWN;
		}
		return 0;
	}
	else
	{
		return -1;
	}
}


static T_InputOpr g_tStdinInputOpr = {
	.name = "stdin",
	.DeviceInit = StdinDeviceInit,
	.DeviceExit = StdinDeviceExit,
	.GetInputEvent = StdinGetInputEvent,
};

int StdinRegister(void)
{
	return RegisterInputOpr(&g_tStdinInputOpr);
}

